#include "stdio.h"
#include "stdlib.h"
#include "SDL/SDL.h"

#include "SDLfunctions.h"
#include "GameEngine.h"
#include "Board.h"
#include "HumanPlayer.h"
#include "DumbAi.h"
#include "position_t.h"

#define UNUSED_ARG_HACK argv;argc;

static const int sizeCase = 40;


void draw_grid(SDL_Surface *screen, Uint32 color) {
	int x = 0, y = 0;
	for (x=sizeCase; x<screen->w; x+=sizeCase) {
		draw_line(screen, position_t(x,2*sizeCase), position_t(x,screen->h), color);
	}
	for (y=2*sizeCase; y<screen->h; y+=sizeCase) {
		draw_line(screen, position_t(sizeCase,y), position_t(screen->w-sizeCase,y), color);
	}
}

void draw_case(SDL_Surface *screen, player_t player, position_t p, Board::case_e caseToDisplay) {
	int x = p.x*sizeCase+sizeCase, y = p.y*sizeCase+2*sizeCase;
	Uint32 green = SDL_MapRGB(screen->format, 0, 255, 0);
	Uint32 purple = SDL_MapRGB(screen->format, 128, 0, 255);
	Uint32 red = SDL_MapRGB(screen->format, 255, 0, 0);
	Uint32 white = SDL_MapRGB(screen->format, 255, 255, 255);
	Uint32 color;

	if (caseToDisplay == Board::CASE_BALL) {
		if (player.isP1()) color = red;
		else color = purple;
	}
	else if (caseToDisplay == Board::CASE_EMPTY) color = green;
	else color = white;

	draw_fill_rect(screen, position_t(x,y), position_t(x+sizeCase-1,y+sizeCase-1), color);
}

void highlight_goals(SDL_Surface *screen) {
	Uint32 purple = SDL_MapRGB(screen->format, 64, 0, 255);
	Uint32 red = SDL_MapRGB(screen->format, 192, 0, 0);

	draw_fill_rect(screen, position_t(0,2*sizeCase), position_t(sizeCase,screen->h-1), red);
	draw_fill_rect(screen, position_t(screen->w-sizeCase,2*sizeCase), position_t(screen->w, screen->h-1), purple);
}

void draw_board(SDL_Surface *screen, GameEngine ge) {
	Board b = ge.getBoard();
	position_t ball = b.getBallPosition();
	player_t player = ge.getCurrentPlayer();
	int i = 0, j = 0;
	Uint32 blue = SDL_MapRGB(screen->format, 0, 0, 255);

	for (i=0; i<Board::w; i++) {
		for (j=0; j<Board::h; j++) {
			if (i==ball.x && j==ball.y) {
				draw_case(screen, player, position_t(i,j), Board::CASE_BALL);
			} else {
				draw_case(screen, player, position_t(i,j), b.getCase(position_t(i,j)));
			}
		}
	}
	draw_grid(screen, blue);
}

void draw_remaining_turns(SDL_Surface *screen, int turnCount) {
	char str[50];
	if (turnCount>=2) sprintf(str, "%d remaining turns.", turnCount);
	else sprintf(str, "%d remaining turn.", turnCount);
	draw_text(screen, str, 40, position_t(screen->w/4+10,70), SDL_MapRGB(screen->format,255,255,0));
}

position_t get_position_from_pixels(int x, int y) {
	int i = (x-sizeCase)/sizeCase;
	if (x < sizeCase) i = -1;
	return position_t(i,(Board::h-y/sizeCase)-1);
}

bool playerIsAI(bool* playersThatAreAi, player_t p){
	if(p.isP1()){
		return playersThatAreAi[0];
	}else if(p.isP2()){
		return playersThatAreAi[1];
	}
	return false;
}

void update(SDL_Surface *screen, GameEngine ge) {
	clear_screen(screen);
	draw_board(screen, ge);
	highlight_goals(screen);
	draw_remaining_turns(screen, ge.turnLimit-ge.getTurnCount());
}


extern "C" int main(int argc, char* argv[]) {
	UNUSED_ARG_HACK;
	GameEngine ge;
	GameInput gi;
	SDL_Surface *screen = NULL;
	SDL_Event event; event.type = 0;
	position_t p;
	bool gameOver = false;
	char playerMessage[50];
	Player *players[2];
	player_t winner;
	Uint32 playerColorMessage = 0;
	// For quick switching between players.
	if(false){
		players[0] = new DumbAi(GameEngine::P1);
		players[1] = new HumanPlayer(0,0,sizeCase);
	}else if(true){
		players[0] = new HumanPlayer(0,0,sizeCase);
		players[1] = new DumbAi(GameEngine::P2);
	}else{
		players[0] = new HumanPlayer(0,0,sizeCase);
		players[1] = new HumanPlayer(0,0,sizeCase);
	}

	// Init.
	screen = init_screen("Descartes soccer", ge.getBoard().w*sizeCase+sizeCase*2, ge.getBoard().h*sizeCase+2*sizeCase);
	if (!screen) {
		fprintf(stderr, "Unable to start the SDL: %s\n", SDL_GetError());
		return 1;
	}

	// Event loop.
	while (!ge.isGameOver()) {
		
		if (!lock_screen(screen)) {
			return 1;
		}
		
		update(screen, ge);

		unlock_screen(screen);
		SDL_Flip(screen);

		if(ge.getCurrentPlayer().isP1()){
			gi = players[0]->play(ge);
		}else{
			gi = players[1]->play(ge);
		}
		
		if(gi.action==GameInput::REQUEST_EXIT){
			return 0;
		}else{
			ge.step(gi);
		}
		if(ge.getLastInputFailed()){
			printf("Last input failed.\n");
		}
	}

	while (event.type != SDL_QUIT) {
		SDL_WaitEvent(&event);

		if (!lock_screen(screen)) {
			return 1;
		}

		update(screen, ge);

		ge.getWinner(winner);
		if (winner.isP1()) {
			sprintf(playerMessage, "Player 1 win!");
			playerColorMessage = SDL_MapRGB(screen->format, 192, 0, 0);
		}
		else if (winner.isP2()) {
			sprintf(playerMessage, "Player 2 win!");
			playerColorMessage = SDL_MapRGB(screen->format, 64, 0, 255);
		}
		else {
		sprintf(playerMessage, "Draw!");
		playerColorMessage = SDL_MapRGB(screen->format, 0, 0, 0);
		}

		draw_text(screen, playerMessage, 40, position_t(screen->w/3,screen->h/2+screen->h/6), playerColorMessage);

		unlock_screen(screen);
		if (!gameOver) {
			SDL_Flip(screen);
			gameOver = true;
		}
	}

	// End.
	SDL_Quit();
	return 0;
}